V02 predict simultaneously all the forecasts days (2 weeks)
Results
5 Years hitorical data (300 days to test) - X_lenght: 20 weeks. LSTM size? --> (RMSE trn / RMSE test)
Years: 5 - LSTM: 64. X_lenght?
weeks: 5 - LSTM 64. Years?
In [1]:
from __future__ import print_function
import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = (10, 10)
path='/tmp/'
In [2]:
import os
os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"]="1"
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
In [3]:
# Generate seasonal data dataframe
n_cases = 365*10
data=[]
for i in range(n_cases):
t = (i/100.)
s = abs((i%7)-3.5)*2.
data += list(t + s + np.random.randn(1))
index = pd.date_range('1/1/2000', periods=n_cases)
serie = pd.Series(data=data, index=index, name='value')
serie.head
Out[3]:
In [4]:
plt.plot(serie)
Out[4]:
In [5]:
plt.plot(serie['1/1/2002':'2/1/2002'])
Out[5]:
In [6]:
def extract_sequences(serie_np, maxlen=14, maxlen_y=14, step=1):
'''
Cut the serie in redundant sequences of maxlen data
One sequence of length 14 for each day
'''
n_cases = (serie_np.shape[0] - maxlen - maxlen_y) // step
sequences = np.empty((n_cases, maxlen))
next_data = np.empty((n_cases, maxlen_y))
for i in range(0, serie_np.shape[0] - maxlen - maxlen_y, step):
sequences[i] = serie_np[i : i + maxlen]
next_data[i] = serie_np[i + maxlen : i + maxlen + maxlen_y]
return sequences, next_data
#X_trn , y_trn = extract_sequences(seqs, maxlen=14*24, step=1)
In [7]:
# Extract sequences
maxlen = 35 # 20 weeks
maxlen_y = 14
X_trn , y_trn = extract_sequences(serie.as_matrix()[:n_cases-300], maxlen=maxlen, maxlen_y=maxlen_y, step=1)
X_tst , y_tst = extract_sequences(serie.as_matrix()[n_cases-300:], maxlen=maxlen, maxlen_y=maxlen_y, step=1)
print(X_trn.shape, y_trn.shape)
print(X_tst.shape, y_tst.shape)
print(y_tst[0])
In [8]:
# Normalize
range_trn = np.max(X_trn) - np.min(X_trn)
print(range_trn)
X_trn = (X_trn / range_trn) -0.5
y_trn = (y_trn / range_trn) -0.5
X_tst = (X_tst / range_trn) -0.5
y_tst = (y_tst / range_trn) -0.5
In [9]:
def generate_batch(X, y, batch_size=4, limit=-1, shuffle_data=True):
'''
Generate batches for one epoch
Randomize order for each epoch
'''
shuffle_index = [i for i in range(0, X.shape[0], batch_size)]
if shuffle_data:
from random import shuffle
shuffle(shuffle_index)
for i in shuffle_index[:limit]:
yield X[i:i+batch_size], y[i:i+batch_size]
gb = generate_batch(X_trn, y_trn)
print(next(gb))
In [10]:
gpu_options = tf.GPUOptions(allow_growth = True)
sess = tf.InteractiveSession(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=True))
In [11]:
def dense(x, input_size=10, otput_size=1):
W = tf.Variable(tf.truncated_normal([input_size, otput_size], stddev=0.1))
b = tf.Variable(tf.constant(0.1, shape=[otput_size]))
return tf.matmul(x,W) + b
In [12]:
# Parameters
#features = 1
lstm_feat = 64
#Inputs
x_input = tf.placeholder(tf.float32, shape=[None, maxlen], name='x')
x_input_lstm = tf.reshape(x_input, [-1,maxlen, 1])
y_input = tf.placeholder(tf.float32, shape=[None, maxlen_y], name='y')
# Recurrent layer
#lstm1 = tf.nn.rnn_cell.BasicLSTMCell(lstm_feat)
keep_prob = tf.placeholder(tf.float32, name='keep_prob')
lstm1 = tf.contrib.rnn.LSTMCell(lstm_feat, initializer=tf.random_uniform_initializer(-0.1, 0.1, seed=123))
lstm1 = tf.contrib.rnn.DropoutWrapper(lstm1, output_keep_prob=keep_prob)
lstm_out, _ = tf.nn.dynamic_rnn(lstm1, x_input_lstm, dtype=tf.float32, scope='lstm04')
#Final dense layer
y_pred = dense(lstm_out[:,-1,:], input_size=lstm_feat, otput_size=maxlen_y)
print(y_pred)
In [13]:
#y_pred = tf.reshape(dense_out,[-1])
#print(y_pred)
# Loss function
cost = tf.reduce_sum(tf.square(y_pred - y_input))
# Trainer
learning_rate = tf.placeholder(tf.float32, name='learning_rate')
train_step = tf.train.RMSPropOptimizer(learning_rate=learning_rate).minimize(cost)
In [23]:
sess.run(tf.global_variables_initializer())
In [24]:
# Train graph
num_epoch=400
batchSize=256
i=0
lr=0.001
for epoch in range(num_epoch):
c_trn = []
gb = generate_batch(X_trn, y_trn, batch_size=batchSize)
for x_b, y_b in gb:
feed_dict={x_input: x_b, y_input: y_b, learning_rate: lr, keep_prob: 0.9}
_, c = sess.run([train_step, cost], feed_dict=feed_dict)
c_trn += [c]
i += 1
if i%10==0:
c_tst = cost.eval(feed_dict={x_input: X_tst, y_input: y_tst, keep_prob: 1})
print('Epoch: ', epoch, ' - LR: ',lr, ' - Cost: ',np.mean(c_trn, axis=0), ' - Cost test: ',c_tst )
#lr *= 0.99
In [25]:
#Score next 14 days
i=3
p_tst = y_pred.eval(feed_dict={x_input: [X_tst[i]], keep_prob: 1})
print(p_tst)
print(y_tst[i])
# Plot for 1 step forecast
plt.plot(p_tst[0])
plt.plot(y_tst[i])
plt.show()
In [26]:
fig = plt.figure()
for i in range(24):
fig.add_subplot(8,3,i+1)
p_tst = y_pred.eval(feed_dict={x_input: [X_tst[i]], keep_prob: 1})
real_vs_pred = np.array([ p_tst[0], y_tst[i]]).T
plt.plot(real_vs_pred)